-[ 0x06 ]--------------------------------------------------------------------
-[ UPC ]---------------------------------------------------------------------
-[ by GreeN LegenD ]--------------------------------------------------SET-18-


                 Entendiendo los Codigos de Barras (UPC)
                =========================================


                ۳                    
                ۳                    
                ۳                    
                ۳                    
                ۳                    
    1   9      9      9      O      O      O      O      1     8    

                   by GreeN LegenD  - (c) 1999 - SET 18

                          Programa by Falken



                          * COPYRIGHT *
                         ~~~~~~~~~~~~~~~
        (c) Copyright - TODOS los derechos de este texto estan reservados.
        Se puede utilizar, SIEMPRE Y CUANDO se CITE CLARAMENTE su origen
        y AUTOR, FECHA DE PUBLICACION ORIGINAL y esta revista, SET. Para
        cualquier otra consulta mandar E-MAIL a glegend@set.net.eu.org.
        Se debe respetar este (c) incluso usando fragmentos del texto.



 Contenidos
 ==========


                Intro.............. 1
                Origen............. 2
                Hablando claro..... 3
                Partes de un UPC... 4
                     No Base....... 4.1
		     Codigo Pais... 4.2 
                Variaciones........ 5
                Tipos de UPC....... 6
                Ejemplo practico... 7
                Numeracion UPC..... 8
                Haciendo uno....... 9
                URLs de interes... 10





 Intro  1
 ========

 Bueno aqui estoy otra vez, esto se me ocurrio despues de leer algo sobre
 el tema y no se hasta que punto se ha tratado en el "underground" o la gente
 sabe de que va esto. Ademas ninguno de mis compa~eros del Staff escribiria
 sobre esto y por cuestion de variar, si quereis otras cosas comentarlo.
 Esto os puede ser util dado que algunas tarjetas de seguridad usan un
 codigo de barras sin numero y con eso lo podeis averiguar.
 Tambien tiene algunas utilidades en el Super, pero esas os la dejo que las
 penseis vosotros solos. Querias articulos tecnicos Garrulo ? Pues escribe
 a ver.. Espero que entendais la representacion de las barras dado que no
 es nada facil dibujar esto en ASCII. Que esto valga como introduccion a
 lo que es el UPC, el programa que acompa~a a este articulo esta hecho por
 Falken, el mismo explicara su funcionamiento en la fuente. Ante todo gracias
 a Falken por "quitarme" esa carga.

                              GreeN LegenD


 Origen  2
 =========

 (En realidad comienza antes, pero ahorremos espacio, el primer intento de
  algo similar se hizo 20 a~os antes sin llegar a buen puerto..)

 Esta Historia comienza un Junio de 1974 en un Supermercado de Troy, Ohio.
 El super se llamaba "Marsh" y un buen dia de Junio los clientes se
 encontraron que no habia cajera y que ahora todos los productos llevaban
 pegado una etiqueta de fondo blanco especial. El CODIGO DE BARRAS, conocido
 tecnicamente por UPC, Universal Product Code. Estos asombrados clientes
 llegaron a la caja y en esta habia un peque~o scaner laser, el que todos
 vosotros ya conoceis y habreis visto muchas veces..
 Luego los clientes recibian un ticket cuando habian acabado de registrar su
 compra y despues pagaban a una unica cajera entregando el ticket. Este
 invento fue inventado por IBM y tiene miles de aplicaciones actualmente.
 Desde los cereales del desayuno hasta los condones pasando por los
 periodicos y los cd-rom. Veremos mas sobre esto depues...
 Observad como se posicionan el haz laser con los dos espejos para que la
 zona sensible este bien definida. Los espejos suelen ser compuestos de varias
 piezas y rara vez son un "solo" espejo.
 El sistema de este puede varias pero lo "comun" es que funcione asi..


 Lector de UPC :

                 A           B            A
                 v           v            v
              ==========.__________.=========
                        | `       |
                        |  `      |
                        S`  `    E
                        S `  ,   E
              Datos___/|  `. ,   |
                        |__eeeeee__|

 A = Protectores
 B = Zona sensible/lectora de UPC (cristal de espejo)
 S = Laser-Escaner lector de UPCs
 E = Espejo de posicion de haz laser
 e = Espejo especial (multiples, tambien posicion laser)


Hablando Claro  3
=================

 Antes de empezar con lo complicado vamos a ver por alto como va esto de los
 codigos de barras. Que quede claro que en esto la gente va bastante libre
 y cada pais hace un poco lo que le da la gana, pero se siguen una guias.
 Se suele tratar de que todos tengan 13 (+1 el de CRC) digitos, cada UPC se
 divide en DOS grandes bloques, Numero base y Numero de articulo. Cada
 digito en un UPC esta compuesto por 7 barras de un tama~o que tiene que ser
 el mismo en cada UPC. Eso no significa que no pueda haber codigo de barras
 mucho mas grandes, simplemente que siempre ha de *estar* todo en escala.

 Cada pais suele tener (y realmente es *suele*) asignados un rango de
 numeros para que sus compa~ias nacionales creen sus UPC. Algunos tienen
 varios bloques asignados en numeraciones no consecutivas. En cada pais hay
 una entidad que se encarga de gestionar la peticion y concesion de las
 numeraciones de UPC a las empresas y sus procuctos.
 El UPC se convirtio en algo obligatorio en la Union Europea en 1977,
 exactamente el 1 Julio de 1977. Esta ley se donomino "EAN" que significa
 European Article Number ,numero de articulo europeo. Desde entonces TODO
 tiene un codigo de barras. Algunas empresas han desarrollado sus propios
 sistemas de UPC "propietarios y no abiertos" Nokia y Sony son dos ejemplos.
 Despues de leer esto podreis crear con facilidad programas para implementar
 UPCs.



Partes de un UPC 4
==================

 Vamos a ver de que esta hecho un UPC realmente, hay algo detras de esas
 lineas y numeros. El UPC tiene cuatro partes principales estas son :


 *  - Bloque Inicial de DATOS -> 3 Barras

                             /Sub-Numero/s Asignado/s al pais.   -> 21 Barras
 *  - Numero Base (7 Digitos)
                             \Sub-Numero Asignado a la compa~ia. -> 21 Barras

 *  - Numero de Articulo (5 Digitos) -> 35 Barras

 *  - Numero de Autentificacion (CRC) -> 7 Barras



Barras de un UPC :
------------------

    Comienzo de DATOS  -> 3     
    Numero Base        -> 42
    DATOS Intermedios  -> 5
    Numero Articulo    -> 35
    CRC del UPC        -> 7
    Final DATOS        -> 3
  ---------------------------
     Total Barras = 95

 Esto es de un Codigo de barras de 14 digitos totales, los hay de 10 (Jap)
 y  de 22 (CD-Barcode). Pero este el normal. Tambien hay muchos mas.. pero
 esos para otro momento.


Que son las Barras?
-------------------

 Se define como barra a la linea transparente o no con una longitud
 delimitada por su tarea en un UPC. Veamos un ejemplo..
 En algunos casos doy como color transparente este  para que se vea
 con mas claridad.


                    1234567  <- Cada Digito esta compuesto por 7 barras..
      Barras   ->   vvvvvvv
                    ۰ 
                    ۰ 
                    ۰ 
                    ۰ 
                    ۰ 
                       1    <- Digito perteneciente a Tipo A


          = transparente  = relleno



Numero Base y Articulo
----------------------

 Cada pais tiene asignados unos numeros he aqui algunos ejemplos.
 Existe una entidad que otorga numeros a los productos. Pero tened en cuenta
 que la numeracion puede cambiar si la compa~ia es internacional y tiene
 varias oficinas por el mundo dado que un mismo producto puede estar hecho
 en varios sitios a la vez. Hay que tener encuenta que el primer bloque de
 numeracion pertenece siempre a el numero respectivo de la empresa o de quien
 ponga el producto a la venta, siendo genrico asi...


No Articulo
-----------

 Sobaos Martinez tendria          <841264 00051>
 Magdalenas Martinez tendria      <841264 00049>

 La compa~ia Martinez SA. tendria <841262 xxxxx> como numero base para
 todos sus UPC, independientemente de el numero de producto.

 Al ser productos distintos de una misma marca, claro esto?
 Teniendo los sobaos un PIC (Product Identification Code) de 00051 y las
 magdalenas un PIC de 00049 dentro de su UPC.


No Base         4.1
===================

 Entonces tenemos 841xyz AAAAA, siendo 841xxx un numero base que pertenece
 a Espa~a y siendo xyz el SUB-NUMERO asignado a la compa~ia. Y AAAAA el
 numero del articulo en cuestion.


        Numero Base : AAA-BBB     A: Pais
                                  B: Compa~ia


Codigos de Paises	4.2
===========================

 Esta lista no es ni mucho menos completa, pero es puede servir de referencia.
 Tened en cuenta que un producto puede estar hecho en Hong Kong y tener un UPC
 de USA, este es por que el UPC de un producto se solicito en USA. El upc solo
 indica el pais donde se solicito el UPC, no EL PAIS DE ORIGEN DEL PRODUCTO.


	00 	-	
	01	 \	
	03	   = USA & Canada 
	05	 /	
	06-13   -

	02	Reservado para uso local de almacenes,etc..
	30-37	Francia
	400-440	Alemania
	45	Japon
	46	Federacion Rusa
	471	Taiwan
	474	Estonia 
	475	Letonia
	477	Lituania 
	479	Sri Lanka 
	480	Filipinas 
	482	Ukraine 
	484	Moldavia 
	485	Armenia 
	486	Georgia 
	487	Kazagistan
	489	Hong Kong (HK)
	49	Japon
	50	UK
	520	Grecia 
	528	Libano 
	531	Macedonia 
	535	Malta 
	539	Irlanda
	54	Belgica & Luxemburgo 
	560	Portugal 
	569	Iceland 
	57	Dinamarca 
	590	Polonia
	594	Rumania 
	599	Hungria 
	600-601	Sur Africa 
	609	Mauritania
	611	Marruecos
	613	Algeria 
	619	Tunez
	622	Egipto 
	625	Jordania 
	626	Iran 
	64	Finlandia 
	690-692	China 
	70	Norway 
	729	Israel 
	73	Suecia 
	740-745	Guatemala, El Salvador, Honduras, Nicaragua, Costa Rica & Panama 
	746	Republica Dominicana 
	750	Mexico 
	759	Venezuela 
	76	Suiza 
	770	Colombia 
	773	Uruguay 
	775	Peru
	777	Bolivia 
	779	Argentina 
	780	Chile 
	784	Paraguay 
	785	Peru 
	786	Ecuador 
	789	Brazil 
	80 -83	Italia 
	84	Espa~a
	850	Cuba 
	858	Slovakia 
	859	Chequia 
	860	Yugoslavia 
	869	Turkia
	87	Holanda 
	880	Korea del Sur 
	885	Tailandia 
	888	Singapur 
	890	India 
	893	Vietnam 
	899	Indonesia 
	90 -91	Austria 
	93	Australia 
	94	Nueva Zelanda 
	955	Malasia 
	977	ISSN (International Standard Serial Number for periodicals) 
	978	ISBN (International Standard Book Number) 
	979	ISMN (International Standard Music Number) 
	980	Productos devueltos
	99	Cupones



Variaciones   5
===============

 Como en toda cosa que compleja existen sus variaciones y excepciones.
 Vamos a ver algunas. Segun les de a algunas compa~ias usaran la combinacion
 en el segundo bloque del Numero Base, de A-B-B o A-B-A o incluso A-A-B.
 Los CD-ROM tienen un Barcode, muchas CD-R normales NO pueden leer ni
 escribir este campo. Solo lo graban algunos modelos y las stampadoras
 de plateados. Este UPC es de 20 digitos, y usa un sistema distinto que no
 vamos a explicar hoy. Japon usa su propia implementacion de los UPC con
 un formato habitualmente de 5 + 5, 5 digitos numero base + 5 numero de
 producto, dejando el CRC fuera sin BARRAS, este sistema es EXTREMADAMENTE
 facil de romper y utilizar a nuestro favor. Las publicaciones escritas
 (y muchas mas ahora) llevan ya un "extra" que es un peque~o UPC que tiene
 los digitos sobre si y no debajo. siendo el resto normal y sin CRC. Vamos
 que ese no es problema. Por ahora no se me ocurre nada mas que a~adir aqui..

 Algunos ejemplos..

    |||||||||||||||||
  <4||234567||00012||9>   * Sin barras de CRC y con <> como marcadores..
                            Pero con el digito del CRC..
   ||||||||||||||||
  1||12345||12364||       * Japones sin CRC (ni barras ni digito) 5+5

   |||||||||||||||||| 45664
  7||456789||001238|| |||||   *Extra a~adido con CRC


Tipos de UPC	6
=================

             Implementaciones Diversas de los UPC
	
 En este articulo solo hablaremos sobre los UPC standard iniciales, 
 los de los productos normales( 13 Digitos)  y no hablaremos del resto.
 Esto no quiere decir que no haya mas, aqui teneis una corta lista. Si 
 quereis buscar mas informacion visitad la web de Hewlett-Packard.
 Si os interesa informacion a fondo y detallada en AIM-USA venden todo
 tipo de manuales sobre UPC.

 Tipos de UPCs....

 Codabar         (HP)
 Codablock       (UPC de 2 Dimensiones)
 Code 1
 Code 16K
 Code 11         (HP) & (AIM-USA)
 Code 39 
 Code 49
 Code 93         (HP) & (AIM-USA)
 Code 128         *Este es el de los CDs*
 Data Matrix     [Data Code]
 EAN             (Tipo UPC/EAN)
 Interleaved 2 of 5
 MaxiCode
 MSI Code
 NW-7 Code
 Plessey Code
 PDF417
 Postnet         [Correos USA]
 Telepen         (SB Electronics)
 Vericode

 Y existen algunos mas, dada su gran cantidad nosotros no limitamos
 a el mas extendido. si quereis mas informacion o bibliografia sobre
 estos UPCs en la revista ID Magazine encontrareis todo lo necesario.



Un ejemplo practico     7
=========================

 Vamos a ver ahora como funciona todo lo que hemos visto con anterioridad en
 un UPC real, desglosandolo en sus distintas partes.. Es imposible meter la
 representacion a escala de el UPC en una pantalla, para su mejor
 entendimiento *no* he partido este UPC, cursor a la derecha -> -> ->
                                                                                  CRC del UPC (7)
 Bloque de Comienzo de DATOS (3 barras)                                                     | (7 barras)
    |                                     Bloque Intermedio de DATOS (5 barras)            |
    |     Numero Base 7 Digitos (400264)          |        Numero de Articulo (00005)    __|__
    |                     |     (42 barras)       |                   |   (35 barras)        `     Bloque Fin de DATOS UPC
    |                     |                      _|_    .----------------------------.  |     |_____|
   _|_.----------------------------------------.|   | .                              `.|     || |
   v vv                                        vv   vv                                 vv     vv v
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
 4    0      0      0      2      6      4      0      0      0      0      5      7   


 (4) 0-A 0-B 0-A / 2-A 6-B 4-B                           0-C 0-C 0-C 0-C 5-C              7-C
                 |___________|                          |_________________|             |_____CRC es SIEMPRE Tipo C
                      *Esto cambia segun sea un UPC de           *Esto es siempre C, lo mires 
                      un tipo u otro.. A-B-B / A-B-A              como quieras..

 Estos comentarios de arriba se refieren al tipo de Numeracion a utilizar
 segun la zona en la que se coloque el digito...

Numeracion UPC  7
=================

 He aqui los tres tipos de numeracion mas usados. Usadlos con sabiduria.. :)
 La forma de usar cada uno de ellos se explica en la proxima seccion, en
 como construir tu propio UPC.

                ___________________________________________
               |                                           |
               |     = Bloque Blanco (Transparente)       |
               |                                           |
               |     = bloque Negro  (Color de relleno)   |
               |___________________________________________|




                                    Barra Numero

                              /          |         \
                           1234567   1234567   1234567
                Numero     vvvvvvv   vvvvvvv   vvvvvvv
                 |  .--------------,----------.---------.
                 `->|0   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |1   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |2   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |3   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |4   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |5   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |6   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |7   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |8   ->۰ | ۰  | ۰۰ |
                    |--------------|----------|---------|
                    |9   ->۰ | ۰  | ۰۰ |
                    `--------------`---------`--------
                        TIPO "A"  - TIPO "B"  - TIPO "C"


Haciendo uno    9
=================

 Vamos a hacer uno normal sin CRC...

 1. Selecionar el Codigo del Pais..  780
 2. Selecionar la compa~ia..         0547
 3. No del Producto..                04953

 A ello..

 4. Poner el primer digito fuera. (7)
 5. Insertar Bloque de DATOS INICIAL
 6. Selecionar Tipo de Numeracion para el No Base (800547)
 7. Al ser un UPC normal seguiremos A-B-A para los primeros 3 (No cambiar..)
 8. Los segundos 3 digitos los haremos esta vez con A-B-B, para un UPC de Esp.
 9. Insertamos el Bloque Intermedio de DATOS..

  Parte I

       ۰۰۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰۰۰
     7    8(a)   0(b)   0(a)   5(a)   4(b)   5(a)

 10. Generamos 04953 con C.
 11. Cerramos el UPC con un Bloque de DATOS FINAL.


  Parte II

       ۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰
       ۰۰۰۰۰۰۰۰۰۰
          0      4      9      5      3   

  12. Ya tienes tu UPC tipo Hispano no 780054504953...

  13. Mira el resultado..

   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
   ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰
 7    8(a)   0(b)   0(a)   5(a)   4(b)   5(a)   0      4      9      5      3   


 URLs de Interes	10
 =========================

 Sobre el ISBN y el EAN  encontrareis informacion aqui...

  http://www2.hp.com/HP-COMP/barcode/sg/Misc/upc.html#A1.4.2.1  [EAN]
  http://www.adams1.com/pub/russadam/isbn.html 			[ISBN]

 Existen varios programas para generar UPCs, fuentes TTF y tonterias varias
 pero el mejor de todos los que he visto es Xbarcode, un programa gratuito
 hecho por un par de Alemanes de Stuttgart, funciona bajo X-Window y lo
 podreis encontrar si haceis una pequena busqueda por ahi..

   GreeN LegenD - (c) SET 1998 - A~o III - glegend@set.net.eu.org



 APENDICE 1: El CRC de los UPC
 =============================

A ver, paso. Con permiso. Atencion lectores! Desde ahora el que habla es
Falken ;)

GreeN LegenD me ha pedido que os cuente en pocas palabras como se calcula el
digito de control o CRC de un codigo de barras. Y eso es precisamente lo que
voy a hacer.

Para empezar, el procedimiento es el mismo ya sea un codigo de barras que
siga el estandar UPC o el estandar EAN. Solo varia ligeramente la forma de
contar.

En ambos casos, se suman los digitos de las posiciones impares. El resultado
se multiplica por tres, y se le a~ade la suma de los digitos pares.

Lo que quede para alcanzar el proximo multiplo de 10 es el digito de control.

Como siempre, los ejemplos aclaran las explicaciones.

En el caso de un UPC:

UPC-A: 63692092284
       IPIPIPIPIPI (No, no le gusta tanto el IP. I-Impar; P-Par)

     (6 + 6 + 2 + 9 + 2 + 4) x 3 -> 87
     3 + 9 + 0 + 2 + 8 -----------> 22
                                   ----
                                   109 => 10 - (109 % 10) = 1

     El digito de control es 1

EAN13: 978156592284
       PIPIPIPIPIPI (Este no pide paso ;) I-Impar; P-Par)

     (7 + 1 + 6 + 9 + 2 + 4) x 3 -> 87
     9 + 8 + 5 + 5 + 2 + 8 -------> 37
                                   ----
                                   124 => 10 - (122 % 10) = 6


Ya veis que no es ningun misterio. Ademas, en el numero especial de la
UnderCON del 97 teneis una explicacion sobre el EAN 13.

Y aqui el codigo fuente del programa. No es una maravilla, pero cumple su
cometido.

<++> set_018/upc/ean.c
/* EAN
 * por Falken
 *
 * (C) SET, 1999
 * 
 *      Por hacer:
 *         - Soporte para distintos tipos de codificacion.
 *         - Soporte para cifras suplementarias.
 *
 * Este programa lee de la linea de comandos los digitos correspondientes a
 * un codigo de barras EAN 13, con o sin digito de CRC. Calcula el CRC y
 * muestra la secuencia binaria correspondiente al codigo de barras.
 *
 *      0 - Espacio en blanco
 *      1 - Espacio en negro
 *
 *  *NIX/Linux: gcc -o ean ean.c
 *  Otros: A saber.
 *
 * ./ean codigo-1 codigo-2 ... codigo-n
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*
 * Esta es la tabla que indica la secuencia AB a seguir en el primer bloque
 * del codigo de barras de un EAN 13 en funcion del primer digito.
 */

static const char patron[10] = { 0x00, 0x34, 0x2c, 0x1c, 0x32,
				 0x26, 0x0e, 0x2a, 0x1a, 0x16 };

struct codigo
{
    unsigned char cifras[256];
    struct codigo *sig;
};

int
main(int argc, char **argv)
{
    unsigned char *cd;
    int i, j, crc, marca;
    struct codigo *code_p = 0x00, *head = 0x00;

    if (argc < 2)
    {
	printf("Usar: %s codigo-1, codigo-2... codigo-n\n", argv[0]);
	exit(0);
    }

/*
 * Vamos a crear una lista con todos los argumentos pasados por linea de
 * comandos.
 */

    for (i = 1; (cd = argv[i++]); )
    {
	if (!head)
	{
	    if (!(head = (struct codigo *)malloc(sizeof(struct codigo))))
	    {
		perror("Error en malloc");
		exit(1);
	    }
	    strncpy (head -> cifras, cd, sizeof (head -> cifras));
	    head -> sig = 0x00;
	    code_p = head;
	}
	else
	{
	    if (!(code_p->sig = (struct codigo *)malloc(sizeof(struct codigo))))
	    {
		perror("Error en malloc");
		exit(1);
	    }
	    code_p = code_p -> sig;
	    strncpy (code_p -> cifras, cd, sizeof(code_p -> cifras));
	    code_p -> sig = 0x00;
	}
    }

    if (!(code_p->sig = (struct codigo *)malloc(sizeof(struct codigo))))
    {
	perror("Error en malloc");
	exit(1);
     }
    code_p = code_p -> sig;
    code_p -> sig = 0x00;

/*
 * Y ahora vamos a tratar cada argumento.
 */

    for ( code_p = head; code_p -> sig; code_p = code_p -> sig)
    {

/*
 * Si no son cifras, no vale.
 */

	for (i = 0; i < strlen (code_p->cifras); i++)
	    if ((code_p->cifras[i] < 0x30) || (code_p->cifras[i] > 0x39))
	    {
		j = 1;
		continue;
	    }
	    else j = 0;
	if (j == 1)
	{
	    printf ("Cifra CB erronea: %s\n", code_p->cifras);
	    continue;
	}

/*
 * Y tampoco si tiene menos de 12 digitos o mas de 13.
 */

	if (strlen (code_p -> cifras) < 12 )
	{
	    printf("Codigo demasiado peque~o para EAN 13: %s\n", code_p->cifras);
	    continue;
	}
	if (strlen (code_p -> cifras) > 13 )
	{
	    printf("Codigo demasiado grande para EAN 13: %s\n", code_p->cifras);
	    continue;
	}
	j = 0;
	crc = 0;

/*
 * Ahora calculamos el CRC. Recordemos que las cifras estan en ASCII, por
 * lo que tendremos que pasarlas a int antes de hacer calculos. La forma mas
 * rapida para un solo digito: '3' - 0x30 = 3
 */

	for (i = 1; i < 12; i += 2)
	    j += code_p -> cifras[i] - 0x30;
	j *= 3;
	for (i = 0; i < 12; i += 2)
	    crc += code_p -> cifras[i] -0x30;
	crc += j;
	crc = 10 - (crc % 10);
	if (strlen (code_p -> cifras) == 13)
	   if (code_p->cifras[12] != (crc + 0x30))
	   {
	       printf ("Codigo CRC erroneo!\n");
	       continue;
	   }
	marca = code_p->cifras[0] - 0x30;
	j = 1;
	code_p->cifras[12] = crc + 0x30;

/*
 * Y ahora a por el codigo de barras en EAN 13.
 */

	printf ("Generando codigo de barras: %s\n", code_p->cifras);
	printf ("CRC            : %c\n", code_p->cifras[12]);
	printf ("Marca inicial  : 101\n");
	printf ("Primer bloque  : ");
	for (i = 1; i < 7; i++)
	{
            if (patron[marca] & j)

                /* O es B */

		switch (code_p->cifras[i] - 0x30)
		{
		    case 0 : printf ("0100111"); break;
		    case 1 : printf ("0110011"); break;
		    case 2 : printf ("0011011"); break;
		    case 3 : printf ("0100001"); break;
		    case 4 : printf ("0011101"); break;
		    case 5 : printf ("0111001"); break;
		    case 6 : printf ("0000101"); break;
		    case 7 : printf ("0010001"); break;
		    case 8 : printf ("0001001"); break;
		    case 9 : printf ("0010111"); break;
		}
	    else

                /* O es A */

		switch (code_p->cifras[i] - 0x30)
		{
		    case 0 : printf ("0001101"); break;
		    case 1 : printf ("0011001"); break;
		    case 2 : printf ("0010011"); break;
		    case 3 : printf ("0111101"); break;
		    case 4 : printf ("0100011"); break;
		    case 5 : printf ("0110001"); break;
		    case 6 : printf ("0101111"); break;
		    case 7 : printf ("0111011"); break;
		    case 8 : printf ("0110111"); break;
		    case 9 : printf ("0001011"); break;
		}
	    j *= 2;
	}
	printf ("\n");
	printf ("Marca central  : 01010\n");
	printf ("Segundo bloque : ");
	for (i = 7; i < 13; i++)
	    switch (code_p->cifras[i] - 0x30)
	    {
		case 0 : printf ("1110010"); break;
		case 1 : printf ("1100110"); break;
		case 2 : printf ("1101100"); break;
		case 3 : printf ("1000010"); break;
		case 4 : printf ("1011100"); break;
		case 5 : printf ("1001110"); break;
		case 6 : printf ("1010000"); break;
		case 7 : printf ("1000100"); break;
		case 8 : printf ("1001000"); break;
		case 9 : printf ("1110100"); break;
	    }
	printf ("\n");
	printf ("Marca final    : 101\n\n");
    }
    return (0); /* S'acabo */
}
<-->


